home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993 October: Windmill on DISC / ADC Developer CD (1993-10) (''Windmill On DISC'')_iso / Dev.CD Oct 93.iso / System Software / U.S. System Software / System 7 Pro™ Beta 11 / Development Tools / Sample Code / Standard Mail / CollaboDraw (w⁄DigiSign) / digisig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-11  |  13.1 KB  |  611 lines  |  [TEXT/KAHL]

  1. /*-------------------------------------------------------------------------------------
  2.  *
  3.  * Simple Sample AOCE Application Framework
  4.  *
  5.  * ©1991-1993 Apple Computer
  6.  *
  7.  -------------------------------------------------------------------------------------*/
  8. /*
  9.  * digisig.c -- digital signature stuff
  10.  *
  11.  * change history:
  12.  *
  13.  * SJF        03/08/93        1.0b1        initial coding
  14.  *
  15.  */
  16.  
  17. #ifndef __TYPES__
  18. #include <Types.h>
  19. #endif
  20.  
  21. #ifndef __FOLDERS__
  22. #include <Folders.h>
  23. #endif
  24.  
  25. #ifndef __FILES__
  26. #include <Files.h>
  27. #endif
  28.  
  29. #ifndef __ERRORS__
  30. #include <Errors.h>
  31. #endif
  32.  
  33. #ifndef __RESOURCES__
  34. #include <Resources.h>
  35. #endif
  36.  
  37. #ifndef __DIGITALSIGNATURE__
  38. #include <DigitalSignature.h>
  39. #endif
  40.  
  41. #include "const.h"
  42. #include "mytypes.h"
  43. #include "globals.h"
  44. #include "utils.h"
  45. #include "windowstuff.h"
  46. #include "strconst.h"
  47. #include "mymenus.h"
  48. #include "draw.window.h"
  49. #include "IconSuites.h"
  50.  
  51. #include "digisig.h"
  52.  
  53.  
  54. #define    kDSIGPattern    7
  55. #define    kDSIGFrameSize    2
  56.  
  57. // static globals
  58.  
  59. static short gDSTempRefNum;
  60. static FSSpec gDSTempFSpec;
  61.  
  62. // routines
  63.  
  64. OSErr InitDigitalSignatures(void)
  65. {    
  66.     OSErr err;
  67.     
  68.     gShowSigners = false;
  69.     
  70.     err = FindFolder(kOnSystemDisk,kTemporaryFolderType,true,&gDSTempFSpec.vRefNum,&gDSTempFSpec.parID);
  71.     if (err!=noErr)
  72.         return err;
  73.     GetResString((StringPtr)&gDSTempFSpec.name,kTempDSFileID,kTempDSFile);
  74.     
  75.     FSpCreateResFile(&gDSTempFSpec,kAppCreator,'????',smRoman);
  76.     if (ResError()==dupFNErr) {
  77.         FSpDelete(&gDSTempFSpec);
  78.         FSpCreateResFile(&gDSTempFSpec,kAppCreator,'????',smRoman);
  79.     }
  80.     if (ResError()==noErr)
  81.         gDSTempRefNum = FSpOpenResFile(&gDSTempFSpec,fsRdWrPerm);
  82.         
  83.     return ResError();
  84. }
  85.  
  86.  
  87. void ExitDigitalSignatures(void)
  88. {
  89.     CloseResFile(gDSTempRefNum);
  90.     FSpDelete(&gDSTempFSpec);
  91. }
  92.  
  93.  
  94. void DSIGSetupSignMenu(WindowPtr window,WInfoPtr infoPtr)
  95. {
  96.     MenuHandle theMenu;
  97.     ShapeListPtr shapeList;
  98.     Boolean gotSigned;
  99.     
  100.     theMenu = GetMHandle(kSignMenu);
  101.  
  102.     if (!gHasAOCE) {
  103.         DisableItem(theMenu,0);
  104.         return;
  105.     }
  106.     
  107.     EnableAllMenuItems(theMenu);
  108.     
  109.     if (!CheckShapeSelected(window,infoPtr))
  110.         DisableItem(theMenu,kSignItem);
  111.     
  112.     gotSigned = false;
  113.     for (shapeList=infoPtr->data; shapeList!=nil; shapeList=shapeList->next) {
  114.         if ((shapeList->isSigned) && (shapeList->selected))
  115.             gotSigned = true;
  116.     }
  117.     if (!gotSigned)
  118.         DisableItem(theMenu,kVerifyItem);
  119.     
  120.     CheckItem(theMenu,kShowSignItem,gShowSigners);
  121. }
  122.  
  123.  
  124. void DSIGOpenFile(WInfoPtr infoPtr)
  125. {
  126.     DigSigListPtr    dsigList,newDSIG;
  127.     ShapeListPtr    shapeList;
  128.     
  129.     dsigList = nil;
  130.     
  131.     for (shapeList=infoPtr->data; shapeList!=nil; shapeList=shapeList->next) {
  132.         if (shapeList->isSigned) {
  133.             newDSIG = NewPtrChk(sizeof(DigSigList));
  134.             if (MemError()!=noErr)
  135.                 return;
  136.             newDSIG->shape = shapeList;
  137.             newDSIG->signatureID = shapeList->signatureID;
  138.             newDSIG->inTemp = false;
  139.             newDSIG->shouldDelete = false;
  140.             newDSIG->next = dsigList;
  141.             dsigList = newDSIG;
  142.             shapeList->digSig = newDSIG;
  143.         }
  144.         else
  145.             shapeList->digSig = nil;
  146.     }
  147.     
  148.     infoPtr->otherData[kDSIGData] = dsigList;
  149. }
  150.  
  151.  
  152. void DSIGCloseFile(WInfoPtr infoPtr)
  153. {
  154.     DigSigListPtr dsigList,prevSig;
  155.     short saveResFile;
  156.     Handle resHandle;
  157.     
  158.     saveResFile = CurResFile();
  159.     UseResFile(gDSTempRefNum);
  160.     
  161.     dsigList=infoPtr->otherData[kDSIGData];
  162.     while (dsigList!=nil) {
  163.         if (dsigList->inTemp) {
  164.             SetResLoad(false);
  165.             Get1Resource(kSignatureResType,dsigList->signatureID);
  166.             RmveResource(resHandle);
  167.             SetResLoad(true);
  168.         }
  169.         prevSig = dsigList;
  170.         dsigList = dsigList->next;
  171.         DisposPtrChk(prevSig);
  172.     }
  173.     infoPtr->otherData[kDSIGData] = nil;
  174.     
  175.     UpdateResFile(gDSTempRefNum);
  176.     UseResFile(saveResFile);
  177. }
  178.  
  179.  
  180. void DSIGSaveFile(WInfoPtr infoPtr,short newResRef,Boolean saveACopy)
  181. {
  182.     short saveResFile,oldResRef;
  183.     short newID;
  184.     DigSigListPtr dsigList,oldSig,prevSig;
  185.     Handle resHandle;
  186.         
  187.     oldResRef = infoPtr->resRefNum;
  188.     saveResFile = CurResFile();
  189.  
  190.     prevSig = nil;
  191.     dsigList=infoPtr->otherData[kDSIGData];
  192.     while (dsigList!=nil) {
  193.         if (dsigList->shouldDelete && (dsigList->inTemp || (!saveACopy && (oldResRef==newResRef)))) {
  194.         
  195.             // delete sig resource
  196.             
  197.             if (dsigList->inTemp)
  198.                 UseResFile(gDSTempRefNum);
  199.             else
  200.                 UseResFile(oldResRef);
  201.             SetResLoad(false);
  202.             resHandle = Get1Resource(kSignatureResType,dsigList->signatureID);
  203.             RmveResource(resHandle);
  204.             SetResLoad(true);
  205.             
  206.             // delete old dsig object from list
  207.             
  208.             if (prevSig)
  209.                 prevSig->next = dsigList->next;
  210.             else
  211.                 infoPtr->otherData[kDSIGData] = dsigList->next;
  212.             
  213.             oldSig = dsigList;
  214.             dsigList = dsigList->next;
  215.             DisposPtrChk(oldSig);
  216.         }
  217.         else if (dsigList->inTemp || saveACopy) {
  218.         
  219.             // copy sig resource from temp file (or old doc file) to new document file
  220.             
  221.             if (dsigList->inTemp) {
  222.                 if (!saveACopy) {
  223.                     UseResFile(newResRef);
  224.                     newID = Unique1ID(kSignatureResType);
  225.                 }
  226.                 else
  227.                     newID = dsigList->signatureID;
  228.                 UseResFile(gDSTempRefNum);
  229.             }
  230.             else {
  231.                 newID = dsigList->signatureID;    // keep same ID for save a copy saves
  232.                 UseResFile(oldResRef);
  233.             }
  234.             resHandle = Get1Resource(kSignatureResType,dsigList->signatureID);
  235.             DetachResource(resHandle);
  236.             UseResFile(newResRef);
  237.             AddResource(resHandle,kSignatureResType,newID,"\p");
  238.             if (ResError()!=noErr) {
  239.                 DoError(ResError());
  240.                 return;
  241.             }
  242.             
  243.             // re-point objects to new ID
  244.             
  245.             if (saveACopy==false)
  246.                 dsigList->inTemp = false;
  247.             dsigList->signatureID = newID;
  248.             dsigList->shape->signatureID = newID;
  249.         }
  250.         
  251.         if (dsigList->shouldDelete==false) {
  252.             prevSig = dsigList;
  253.             dsigList = dsigList->next;
  254.         }
  255.     }
  256.     
  257.     UpdateResFile(gDSTempRefNum);
  258.     if (oldResRef)
  259.         UpdateResFile(oldResRef);    
  260.     UpdateResFile(newResRef);    
  261.     UseResFile(saveResFile);
  262. }
  263.  
  264.  
  265. // needed for add/remove mailer, since this disconnects the data from the document, where
  266. // the signatures are stored.  this function copies all of these signature resources into the
  267. // temp file when the user does add or remove mailer
  268.  
  269. void DSIGCopySigsToTemp(WInfoPtr infoPtr)
  270. {
  271.     DigSigListPtr dsigList;
  272.     short saveResFile,docResFile;
  273.     Handle resHandle;
  274.     short newID;
  275.     
  276.     saveResFile = CurResFile();
  277.     docResFile = infoPtr->resRefNum;
  278.     
  279.     dsigList=infoPtr->otherData[kDSIGData];
  280.     while (dsigList!=nil) {
  281.         if (dsigList->inTemp==false) {
  282.             UseResFile(docResFile);
  283.             resHandle = Get1Resource(kSignatureResType,dsigList->signatureID);
  284.             DetachResource(resHandle);
  285.             UseResFile(gDSTempRefNum);
  286.             newID = Unique1ID(kSignatureResType);
  287.             AddResource(resHandle,kSignatureResType,newID,"\p");
  288.             if (ResError()!=noErr) {
  289.                 DoError(ResError());
  290.                 return;
  291.             }
  292.             dsigList->signatureID = newID;
  293.             dsigList->shape->signatureID = newID;
  294.             dsigList->inTemp = true;
  295.         }
  296.         dsigList = dsigList->next;
  297.     }
  298.     
  299.     UpdateResFile(gDSTempRefNum);
  300.     UpdateResFile(docResFile);
  301.     UseResFile(saveResFile);
  302. }
  303.  
  304.  
  305. void DSIGDrawSigner(ShapeListPtr theShape,Point drawOffset)
  306. {
  307.     Rect iconRect;
  308.     Pattern pat;
  309.     
  310.     if (!theShape->isSigned)
  311.         return;
  312.     
  313.     if (!gShowSigners)
  314.         return;
  315.         
  316.     SetRect(&iconRect,theShape->anchor.h+drawOffset.h,theShape->anchor.v+drawOffset.v,
  317.                 theShape->destination.h+drawOffset.h,theShape->destination.v+drawOffset.v);
  318.     FixRect(&iconRect);
  319.     
  320.     GetIndPattern(pat,sysPatListID,kDSIGPattern);
  321.     PenPat(pat);
  322.     PenSize(kDSIGFrameSize,kDSIGFrameSize);
  323.     FrameRect(&iconRect);
  324.     PenNormal();
  325.     
  326.     iconRect.left = iconRect.right - 16;
  327.     iconRect.top = iconRect.bottom - 16;
  328.     PlotIconID(&iconRect,atNone,ttNone,256);
  329. }
  330.  
  331.  
  332. Boolean DSIGHitShape(WindowPtr window,WInfoPtr infoPtr,Point hitPt,Point offsetPos,ShapeListPtr theShape)
  333. {
  334.     Rect dsigBox;
  335.     Boolean returnVal,hitBox;
  336.     Point mousePt;
  337.     SIGContextPtr sigContext;
  338.     OSErr err;
  339.         
  340.     SetRect(&dsigBox,theShape->anchor.h+offsetPos.h,theShape->anchor.v+offsetPos.v,
  341.                     theShape->destination.h+offsetPos.h,theShape->destination.v+offsetPos.v);
  342.     FixRect(&dsigBox);
  343.     dsigBox.left = dsigBox.right-16;
  344.     dsigBox.top = dsigBox.bottom-16;
  345.     
  346.     hitBox = false;
  347.     if (gShowSigners && PtInRect(hitPt,&dsigBox) && theShape->isSigned) {
  348.         while (WaitMouseUp()) {
  349.             GetMouse(&mousePt);
  350.             if (PtInRect(mousePt,&dsigBox)) {
  351.                 if (!hitBox) {
  352.                     hitBox = true;
  353.                     PlotIconID(&dsigBox,atNone,ttNone,257);
  354.                 }
  355.             }
  356.             else {
  357.                 if (hitBox) {
  358.                     hitBox = false;
  359.                     PlotIconID(&dsigBox,atNone,ttNone,256);
  360.                 }
  361.             }
  362.         }
  363.         PlotIconID(&dsigBox,atNone,ttNone,256);
  364.  
  365.         // verify the selected shape
  366.         
  367.         if (hitBox) {
  368.             err = SIGNewContext(&sigContext);
  369.             if (err==noErr) {
  370.                 err = VerifyShape(infoPtr,sigContext,theShape);
  371.                 SIGDisposeContext(sigContext);
  372.             }
  373.             if (err!=noErr)
  374.                 DoError(err);
  375.         }
  376.                         
  377.         returnVal = true;
  378.     }
  379.     else returnVal = false;
  380.     return returnVal;
  381. }
  382.  
  383.  
  384. void CommSign(WindowPtr window)
  385. {
  386.     WInfoPtr infoPtr;
  387.     char hState;
  388.     ShapeListPtr shapeList;
  389.     SIGContextPtr sigContext;
  390.     Size sigSize;
  391.     OSErr err;
  392.     
  393.     if (!IsAppWindow(window))
  394.         return;
  395.                 
  396.     err = SIGNewContext(&sigContext);
  397.  
  398.     if (err==noErr) {
  399.     
  400.         infoPtr = BeginWindowAccess(window,&hState);    
  401.             
  402.         if (err==noErr)
  403.             err = SIGSignPrepare(sigContext,nil,nil,&sigSize);
  404.  
  405.         for (shapeList=infoPtr->data; (err==noErr) && (shapeList!=nil); shapeList=shapeList->next) {
  406.             if (shapeList->selected)
  407.                 err = SignShape(infoPtr,sigContext,shapeList,sigSize);
  408.                 InvalShapeArea(window,infoPtr,shapeList);
  409.         }
  410.     
  411.         SIGDisposeContext(sigContext);
  412.         DSIGSetupSignMenu(window,infoPtr);
  413.         EndWindowAccess(window,hState);
  414.     }
  415.     
  416.     if (err!=noErr)
  417.         DoError(err);
  418. }
  419.  
  420.  
  421. void CommVerify(WindowPtr window)
  422. {
  423.     WInfoPtr infoPtr;
  424.     char hState;
  425.     ShapeListPtr shapeList;
  426.     SIGContextPtr sigContext;
  427.     OSErr err;
  428.         
  429.     if (!IsAppWindow(window))
  430.         return;
  431.  
  432.     err = SIGNewContext(&sigContext);
  433.     if (err==noErr) {
  434.     
  435.         infoPtr = BeginWindowAccess(window,&hState);
  436.             
  437.         for (shapeList=infoPtr->data; (err==noErr) && (shapeList!=nil); shapeList=shapeList->next) {
  438.             if (shapeList->selected)
  439.                 err = VerifyShape(infoPtr,sigContext,shapeList);
  440.         }
  441.     
  442.         SIGDisposeContext(sigContext);
  443.         EndWindowAccess(window,hState);
  444.     }
  445.     
  446.     if (err!=noErr)
  447.         DoError(err);
  448. }
  449.  
  450.  
  451. void CommShowSigners(WindowPtr window)
  452. {
  453.     WInfoPtr infoPtr;
  454.     char hState;
  455.     ShapeListPtr shapeList;
  456.     
  457.     if (!IsAppWindow(window))
  458.         return;
  459.     
  460.     infoPtr = BeginWindowAccess(window,&hState);
  461.  
  462.     gShowSigners = !gShowSigners;
  463.  
  464.     for (shapeList=infoPtr->data; shapeList!=nil; shapeList=shapeList->next) {
  465.         if (shapeList->isSigned)
  466.             InvalShapeArea(window,infoPtr,shapeList);
  467.     }
  468.  
  469.     DSIGSetupSignMenu(window,infoPtr);
  470.     
  471.     EndWindowAccess(window,hState);
  472. }
  473.  
  474.  
  475. /*---------------------------------------------------------------------------------------------*/
  476.  
  477.  
  478. OSErr SignShape(WInfoPtr infoPtr,SIGContextPtr sigContext,ShapeListPtr theShape,Size sigSize)
  479. {
  480.     OSErr err;
  481.     Handle signature;
  482.     short resID;
  483.     short saveResFile;
  484.     DigSigListPtr theSig;
  485.     
  486.     // allocate storage for the signature
  487.     
  488.     signature = NewHandleChk(sigSize);
  489.     if (MemError()!=noErr)
  490.         return MemError();
  491.     
  492.     // process the data for the signature
  493.     
  494.     err = ProcessShapeData(sigContext,theShape);
  495.         if (err!=noErr) {
  496.         DisposHandleChk(signature);
  497.         return err;
  498.     }
  499.     
  500.     // create the signature
  501.     
  502.     HLock(signature);
  503.     err = SIGSign(sigContext,(SIGSignaturePtr)*signature,nil);
  504.     HUnlock(signature);
  505.     
  506.     // bail if the sign didn't succeed
  507.     
  508.     if (err!=noErr)
  509.         return err;
  510.         
  511.     // add the signature to the shape
  512.     
  513.     saveResFile = CurResFile();
  514.     UseResFile(gDSTempRefNum);
  515.     resID = Unique1ID(kSignatureResType);
  516.     AddResource(signature,kSignatureResType,resID,"\p");
  517.     if (ResError()==noErr) {
  518.  
  519.         ReleaseResource(signature);
  520.  
  521.         // see if old shape is already signed-- if so, mark the old signature for deletion
  522.         
  523.         if (theShape->isSigned) {
  524.             theSig = theShape->digSig;
  525.             theSig->shouldDelete = true;
  526.         }
  527.         
  528.         // create the signature object and add it to the list, ref to shape
  529.         
  530.         theSig = NewPtrChk(sizeof(DigSigList));
  531.         if (MemError()!=noErr)
  532.             return MemError();
  533.         theSig->shape = theShape;
  534.         theSig->inTemp = true;
  535.         theSig->shouldDelete = false;
  536.         theSig->next = infoPtr->otherData[kDSIGData];
  537.         infoPtr->otherData[kDSIGData] = theSig;
  538.         theSig->signatureID = resID;
  539.  
  540.         theShape->digSig = theSig;
  541.         theShape->signatureID = resID;
  542.         theShape->isSigned = true;
  543.     }
  544.     else {
  545.         DisposHandleChk(signature);
  546.         err = ResError();
  547.     }
  548.     UpdateResFile(gDSTempRefNum);
  549.     UseResFile(saveResFile);
  550.  
  551.     return err;
  552. }
  553.  
  554.  
  555. OSErr VerifyShape(WInfoPtr infoPtr,SIGContextPtr sigContext,ShapeListPtr theShape)
  556. {
  557.     DigSigListPtr theSig;
  558.     short saveResFile;
  559.     Handle sigHandle;
  560.     OSErr err;
  561.     Size signatureSize;
  562.     
  563.     if (theShape->isSigned==false)
  564.         return noErr;
  565.         
  566.     theSig = theShape->digSig;
  567.     
  568.     saveResFile = CurResFile();
  569.     if (theSig->inTemp)
  570.         UseResFile(gDSTempRefNum);
  571.     else
  572.         UseResFile(infoPtr->resRefNum);
  573.     sigHandle = Get1Resource(kSignatureResType,theSig->signatureID);
  574.     err = ResError();
  575.     UseResFile(saveResFile);
  576.     if (err!=noErr)
  577.         return err;
  578.         
  579.     signatureSize = SizeResource(sigHandle);
  580.     HLock(sigHandle);
  581.     err = SIGVerifyPrepare(sigContext,(SIGSignaturePtr)*sigHandle,signatureSize,nil);
  582.     if (err==noErr) {
  583.     
  584.         // process the data for the signature
  585.         err = ProcessShapeData(sigContext,theShape);
  586.         if (err==noErr) {
  587.             err = SIGVerify(sigContext);
  588.             if (err==noErr)
  589.                 err = SIGShowSigner(sigContext,nil);
  590.         }
  591.     }
  592.     
  593.     ReleaseResource(sigHandle);
  594.     return err;
  595. }
  596.  
  597.  
  598. OSErr ProcessShapeData(SIGContextPtr sigContext,ShapeListPtr theShape)
  599. {
  600.     OSErr err;
  601.     ShapeListPtr shapeList;
  602.     
  603.     err = noErr;
  604.     if (theShape->shapeType==kBeginGroupTag) {
  605.         for (shapeList=theShape->subList; (shapeList!=nil) && (err==noErr); shapeList=shapeList->next)
  606.             err = ProcessShapeData(sigContext,shapeList);
  607.     }
  608.     else
  609.         err = SIGProcessData(sigContext,theShape,kShapeSignLength);
  610.     return err;
  611. }